package drds.server.route.route_strategy;

import java.sql.SQLNonTransientException;

import drds.server.cache.LayeredCache;
import drds.server.config.model.Schema;
import drds.server.route.Route;
import drds.server.route.util.RouteUtil;
import drds.server.server.SessionContext;
import drds.server.server.parser.ServerParse;

public abstract class AbstractRouteStrategy implements IRouteStrategy {

	@Override
	public Route route(SessionContext sessionContext, Schema schema, String sql, int sqlType, LayeredCache cache) throws SQLNonTransientException {

		/**
		 * 处理一些路由之前的逻辑 全局序列号，父子表插入
		 */
		if (beforeRoute(sessionContext, schema, sql, sqlType)) {
			return null;
		}

		/**
		 * SQL 语句拦截
		 */
		String needParseSql = sql;

		Route route = new Route(needParseSql, sqlType);

		/**
		 * rrs携带ServerConnection的autocommit状态用于在sql解析的时候遇到 select ... for
		 * update的时候动态设定RouteResultsetNode的canRunInReadDB属性
		 */
		if (sessionContext != null) {
			route.setAutoCommit(sessionContext.isAutoCommit());
		}

		route = route(route, schema, needParseSql, cache);

		return route;
	}

	/**
	 * 路由之前必要的处理 主要是全局序列号插入，还有子表插入
	 */
	private boolean beforeRoute(SessionContext sessionContext, Schema schema, String sql, int sqlType) throws SQLNonTransientException {

		return (sqlType == ServerParse.INSERT && RouteUtil.processSequence(sessionContext, schema, sql, sqlType)) //
				|| //
				(sqlType == ServerParse.INSERT && RouteUtil.processERChildTable(sessionContext, schema, sql)) //
				|| //
				(sqlType == ServerParse.INSERT && RouteUtil.processInsert(sessionContext, schema, sql, sqlType));//
	}

	/**
	 * 通过解析AST语法树类来寻找路由
	 */
	public abstract Route route(Route route, Schema schema, String sql, LayeredCache cache) throws SQLNonTransientException;

}
